package org.sand.controller;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.Pane;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;
import org.sand.common.util.ProcessExecutor;
import org.sand.vo.FileVo;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
public class Controller implements Initializable {
    @FXML
    private Pane pane;

    @FXML
    private TableColumn<FileVo, CheckBox> selectColumn;

    @FXML
    private TableView<FileVo> tableView;

    @FXML
    private TableColumn<FileVo,String> idColumn,nameColumn,filePathColumn,statusColumn,pidColumn;

    @FXML
    private TextArea textArea;

    private volatile AtomicInteger id = new AtomicInteger(0);

    private ProcessExecutor processExecutor;

    private Cache<Object, Object> cache;

    private String cmdKey="sand.cmd.key";

    private List<String> javaActions= new ArrayList<>();

    private List<FileVo> listFileVo = new ArrayList<>();

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        processExecutor=new ProcessExecutor();
        selectColumn.setCellValueFactory(cellData->cellData.getValue().selected.getCheckBox());
        idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("fileName"));
        filePathColumn.setCellValueFactory(new PropertyValueFactory<>("filePath"));
        statusColumn.setCellValueFactory(new PropertyValueFactory<>("status"));
        pidColumn.setCellValueFactory(new PropertyValueFactory<>("pid"));
        //初始化
        cache = CacheUtil.newLRUCache(100);
        String cmdStr = (String) cache.get(cmdKey+".str");
        if(StrUtil.isNotBlank(cmdStr)){
            textArea.setText(cmdStr);
        }
        //获取java应用的运行数据
        OnActionQuery();

    }
    
    private List<String> getAction(){
        List<String> command = new ArrayList<String>(Arrays.asList("jcmd","-l" ));
        List<String> datas = new ArrayList<>();
        try {
            ProcessExecutor.ProcessExecutorResult result = processExecutor.runCommandWithOut(command);
             datas = (List<String>) result.getData();
             this.javaActions=datas;
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return datas;
    }

    /**
     * 查询运行应用
     */
    @FXML
    void OnActionQuery(){
        List<String> datas = getAction();
        listFileVo=new ArrayList<>();
        datas.forEach(data->{
                String[] spD = data.split(" ");
                if(spD.length>1){
                    FileVo vo = new FileVo();
                    vo.setFileName(spD[1]);
                    vo.setPid(spD[0]);
                    vo.setStatus("已启动");
                    listFileVo.add(vo);
                }
        });
        tableView.getItems().setAll(listFileVo);
    }

    @FXML
    void selectAll(ActionEvent event){
        ObservableList<FileVo> items = tableView.getItems();
            for (FileVo cxCadreInfo:items){
                cxCadreInfo.selected.setSelect(true);
            }
    }

    @FXML
    void noSelectAll(){
        ObservableList<FileVo> items = tableView.getItems();
        for (FileVo cxCadreInfo:items){
            cxCadreInfo.selected.setSelect(false);
        }
    }


    //选择文件夹查询文件数据
    @FXML
    void OnActionNew(ActionEvent event){
        listFileVo.clear();
        DirectoryChooser directoryChooser = new DirectoryChooser();
        directoryChooser.setTitle("选择文件夹");
        // 显示对话框并获取选择的文件夹
        Stage stage = (Stage)pane.getScene().getWindow();
        File selectedDirectory = directoryChooser.showDialog(stage);
        if (selectedDirectory != null) {
            // 处理选中的文件夹
            log.info("Selected Directory: " + selectedDirectory.getAbsolutePath());
        }
        if (selectedDirectory.exists()) {
            String[] fileArray = selectedDirectory.list();
            // 过滤文件获取所有的jar包
            for (String f : fileArray) {
                File file = new File(selectedDirectory.getAbsolutePath()+"/"+f);
                if(!file.getName().endsWith(".jar")){
                    continue;
                }
                FileVo vo = new FileVo();
                vo.setFileName(file.getName());
                vo.setId(String.valueOf(id.incrementAndGet()));
                vo.setFilePath(file.getAbsolutePath());
                vo.setFilerDate(file.lastModified());
                vo.setStatus("未启动");
                listFileVo.add(vo);
                /*if (f.endsWith(".jar")) {
                    log.info("读取jar包为" + f);
                }*/
            }
            tableView.getItems().setAll(listFileVo);
        }
    }

    /*
     * 启动应用功能
    * set JAVA_HOME=%SRC%\jdk1.8.0_45
    * set PATH=%JAVA_HOME%\bin;%PATH%
    * set CLASSPATH=.
    * javaw -jar -Dnutz.profiles.active=prod D:\ksyc_repari\repair-web-api-5.2.7-SNAPSHOT.jar
    * */
    @FXML
    void OnActionOpen(ActionEvent event){
        try {
            ObservableList<FileVo> items = tableView.getItems();
            for (FileVo fileVo:items){
                if(fileVo.selected.isSelected()) {
                    String[] cmds= (String[]) cache.get(cmdKey);
                    if(ObjectUtil.isEmpty(cmds)){
                        notic(Alert.AlertType.WARNING,"请设置启动命令！");
                        return;
                    }
                   // Process resultCmd = Runtime.getRuntime().exec("javaw -jar D:\\dst\\bidding-ks-service-bid-5.1.0.jar");
                    String [] deals=new String[cmds.length];
                    for (int i = 0; i < cmds.length; i++) {
                        deals[i]=cmds[i];
                        if(cmds[i].contains("{}")){
                            String result = StrUtil.format(cmds[i],fileVo.getFilePath());
                            deals[i]=result;
                        }
                    }
                    List<String> command = new ArrayList<String>(Arrays.asList(deals));
                    processExecutor.runCommand(command,true);
                    fileVo.setStatus("触发启动");
                    fileVo.selected.setSelect(false);
                    notic(Alert.AlertType.INFORMATION,fileVo.getFileName()+"系统触发启动成功！");
                }
            }
            tableView.refresh();
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
        }
    }

    /**
     * 提示
     * @param type
     * @param msg
     */
    private void notic(Alert.AlertType type,String msg){
        Alert alert = new Alert(type);
        alert.setTitle("提示");
        alert.setHeaderText("操作提示");
        alert.setContentText(msg);
        alert.showAndWait();
    }

    @FXML
    void submit(ActionEvent event){
        String cmdStr = textArea.getText();
        String[] pp = cmdStr.split("\n");
        cache.put(cmdKey,pp);
        cache.put(cmdKey+".str",cmdStr);
        notic(Alert.AlertType.INFORMATION,"启动命令保存成功");
        textArea.setText(null);
    }

    @FXML
    void OnActionStop(ActionEvent event){
        try {
            ObservableList<FileVo> items = tableView.getItems();
            for (FileVo fileVo:items){
                if(!StrUtil.isBlank(fileVo.getPid())&&fileVo.selected.isSelected()) {
                    List<String> command = new ArrayList<String>(Arrays.asList("taskkill", "/f", "/pid", fileVo.getPid()));
                    ProcessExecutor.ProcessExecutorResult result = processExecutor.runCommandWithOutputHandling(command);
                    items.remove(fileVo);
                    notic(Alert.AlertType.INFORMATION,"系统停止成功！");
                    break;
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error(e.getMessage());
        }

    }



}
